home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / quake.zip / KASCAM17.ZIP / SOURCE / DEMON.QC < prev    next >
Text File  |  1997-02-19  |  11KB  |  364 lines

  1. /*
  2. ==============================================================================
  3.  
  4. DEMON
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. $cd id1/models/demon3
  10. $scale  0.8
  11. $origin 0 0 24
  12. $base base
  13. $skin base
  14.  
  15. $frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
  16. $frame stand10 stand11 stand12 stand13
  17.  
  18. $frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
  19.  
  20. $frame run1 run2 run3 run4 run5 run6
  21.  
  22. $frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10
  23. $frame leap11 leap12
  24.  
  25. $frame pain1 pain2 pain3 pain4 pain5 pain6
  26.  
  27. $frame death1 death2 death3 death4 death5 death6 death7 death8 death9
  28.  
  29. $frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
  30. $frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
  31.  
  32. //============================================================================
  33.  
  34. void()  Demon_JumpTouch;
  35.  
  36. void()  demon1_stand1   =[  $stand1,    demon1_stand2   ] {ai_stand();};
  37. void()  demon1_stand2   =[  $stand2,    demon1_stand3   ] {ai_stand();};
  38. void()  demon1_stand3   =[  $stand3,    demon1_stand4   ] {ai_stand();};
  39. void()  demon1_stand4   =[  $stand4,    demon1_stand5   ] {ai_stand();};
  40. void()  demon1_stand5   =[  $stand5,    demon1_stand6   ] {ai_stand();};
  41. void()  demon1_stand6   =[  $stand6,    demon1_stand7   ] {ai_stand();};
  42. void()  demon1_stand7   =[  $stand7,    demon1_stand8   ] {ai_stand();};
  43. void()  demon1_stand8   =[  $stand8,    demon1_stand9   ] {ai_stand();};
  44. void()  demon1_stand9   =[  $stand9,    demon1_stand10  ] {ai_stand();};
  45. void()  demon1_stand10  =[  $stand10,   demon1_stand11  ] {ai_stand();};
  46. void()  demon1_stand11  =[  $stand11,   demon1_stand12  ] {ai_stand();};
  47. void()  demon1_stand12  =[  $stand12,   demon1_stand13  ] {ai_stand();};
  48. void()  demon1_stand13  =[  $stand13,   demon1_stand1   ] {ai_stand();};
  49.  
  50. void()  demon1_walk1    =[  $walk1,     demon1_walk2    ] {
  51. if (random() < 0.2)
  52.     sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
  53. ai_walk(8);
  54. };
  55. void()  demon1_walk2    =[  $walk2,     demon1_walk3    ] {ai_walk(6);};
  56. void()  demon1_walk3    =[  $walk3,     demon1_walk4    ] {ai_walk(6);};
  57. void()  demon1_walk4    =[  $walk4,     demon1_walk5    ] {ai_walk(7);};
  58. void()  demon1_walk5    =[  $walk5,     demon1_walk6    ] {ai_walk(4);};
  59. void()  demon1_walk6    =[  $walk6,     demon1_walk7    ] {ai_walk(6);};
  60. void()  demon1_walk7    =[  $walk7,     demon1_walk8    ] {ai_walk(10);};
  61. void()  demon1_walk8    =[  $walk8,     demon1_walk1    ] {ai_walk(10);};
  62.  
  63. void()  demon1_run1 =[  $run1,      demon1_run2 ] {
  64. if (random() < 0.2)
  65.     sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
  66. ai_run(20);};
  67. void()  demon1_run2 =[  $run2,      demon1_run3 ] {ai_run(15);};
  68. void()  demon1_run3 =[  $run3,      demon1_run4 ] {ai_run(36);};
  69. void()  demon1_run4 =[  $run4,      demon1_run5 ] {ai_run(20);};
  70. void()  demon1_run5 =[  $run5,      demon1_run6 ] {ai_run(15);};
  71. void()  demon1_run6 =[  $run6,      demon1_run1 ] {ai_run(36);};
  72.  
  73. void()  demon1_jump1    =[  $leap1,     demon1_jump2    ] {ai_face();};
  74. void()  demon1_jump2    =[  $leap2,     demon1_jump3    ] {ai_face();};
  75. void()  demon1_jump3    =[  $leap3,     demon1_jump4    ] {ai_face();};
  76. void()  demon1_jump4    =[  $leap4,     demon1_jump5    ]
  77. {
  78.     ai_face();
  79.  
  80.     self.touch = Demon_JumpTouch;
  81.     makevectors (self.angles);
  82.     self.origin_z = self.origin_z + 1;
  83.     self.velocity = v_forward * 600 + '0 0 250';
  84.     if (self.flags & FL_ONGROUND)
  85.         self.flags = self.flags - FL_ONGROUND;
  86. };
  87. void()  demon1_jump5    =[  $leap5,     demon1_jump6    ] {};
  88. void()  demon1_jump6    =[  $leap6,     demon1_jump7    ] {};
  89. void()  demon1_jump7    =[  $leap7,     demon1_jump8    ] {};
  90. void()  demon1_jump8    =[  $leap8,     demon1_jump9    ] {};
  91. void()  demon1_jump9    =[  $leap9,     demon1_jump10   ] {};
  92. void()  demon1_jump10   =[  $leap10,    demon1_jump1    ] {
  93. self.nextthink = time + 3;
  94. // if three seconds pass, assume demon is stuck and jump again
  95. };
  96.  
  97. void()  demon1_jump11   =[  $leap11,    demon1_jump12   ] {};
  98. void()  demon1_jump12   =[  $leap12,    demon1_run1 ] {};
  99.  
  100.  
  101. void()  demon1_atta1    =[  $attacka1,      demon1_atta2    ] {ai_charge(4);};
  102. void()  demon1_atta2    =[  $attacka2,      demon1_atta3    ] {ai_charge(0);};
  103. void()  demon1_atta3    =[  $attacka3,      demon1_atta4    ] {ai_charge(0);};
  104. void()  demon1_atta4    =[  $attacka4,      demon1_atta5    ] {ai_charge(1);};
  105. void()  demon1_atta5    =[  $attacka5,      demon1_atta6    ] {ai_charge(2); Demon_Melee(200);};
  106. void()  demon1_atta6    =[  $attacka6,      demon1_atta7    ] {ai_charge(1);};
  107. void()  demon1_atta7    =[  $attacka7,      demon1_atta8    ] {ai_charge(6);};
  108. void()  demon1_atta8    =[  $attacka8,      demon1_atta9    ] {ai_charge(8);};
  109. void()  demon1_atta9    =[  $attacka9,      demon1_atta10] {ai_charge(4);};
  110. void()  demon1_atta10   =[  $attacka10,     demon1_atta11] {ai_charge(2);};
  111. void()  demon1_atta11   =[  $attacka11,     demon1_atta12] {Demon_Melee(-200);};
  112. void()  demon1_atta12   =[  $attacka12,     demon1_atta13] {ai_charge(5);};
  113. void()  demon1_atta13   =[  $attacka13,     demon1_atta14] {ai_charge(8);};
  114. void()  demon1_atta14   =[  $attacka14,     demon1_atta15] {ai_charge(4);};
  115. void()  demon1_atta15   =[  $attacka15,     demon1_run1] {ai_charge(4);};
  116.  
  117. void()  demon1_pain1    =[  $pain1,     demon1_pain2    ] {};
  118. void()  demon1_pain2    =[  $pain2,     demon1_pain3    ] {};
  119. void()  demon1_pain3    =[  $pain3,     demon1_pain4    ] {};
  120. void()  demon1_pain4    =[  $pain4,     demon1_pain5    ] {};
  121. void()  demon1_pain5    =[  $pain5,     demon1_pain6    ] {};
  122. void()  demon1_pain6    =[  $pain6,     demon1_run1 ] {};
  123.  
  124. void(entity attacker, float damage) demon1_pain =
  125. {
  126.     if (self.touch == Demon_JumpTouch)
  127.         return;
  128.  
  129.     if (self.pain_finished > time)
  130.         return;
  131.  
  132.     self.pain_finished = time + 1;
  133.     sound (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
  134.  
  135.     if (random()*200 > damage)
  136.         return;     // didn't flinch
  137.  
  138.     demon1_pain1 ();
  139. };
  140.  
  141. void()  demon1_die1     =[  $death1,        demon1_die2 ] {
  142. sound (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);};
  143. void()  demon1_die2     =[  $death2,        demon1_die3 ] {};
  144. void()  demon1_die3     =[  $death3,        demon1_die4 ] {};
  145. void()  demon1_die4     =[  $death4,        demon1_die5 ] {};
  146. void()  demon1_die5     =[  $death5,        demon1_die6 ] {};
  147. void()  demon1_die6     =[  $death6,        demon1_die7 ]
  148. {self.solid = SOLID_NOT;};
  149. void()  demon1_die7     =[  $death7,        demon1_die8 ] {};
  150. void()  demon1_die8     =[  $death8,        demon1_die9 ] {};
  151. void()  demon1_die9     =[  $death9,        demon1_die9 ] {};
  152.  
  153. void() demon_die =
  154. {
  155. // check for gib
  156.     if (self.health < -80)
  157.     {
  158.         sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
  159.         ThrowHead ("progs/h_demon.mdl", self.health);
  160.         ThrowGib ("progs/gib1.mdl", self.health);
  161.         ThrowGib ("progs/gib1.mdl", self.health);
  162.         ThrowGib ("progs/gib1.mdl", self.health);
  163.         return;
  164.     }
  165.  
  166. // regular death
  167.     demon1_die1 ();
  168. };
  169.  
  170.  
  171. void() Demon_MeleeAttack =
  172. {
  173.     demon1_atta1 ();
  174. };
  175.  
  176.  
  177. /*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush
  178.  
  179. */
  180. void() monster_demon1 =
  181. {
  182.     if (deathmatch)
  183.     {
  184.         remove(self);
  185.         return;
  186.     }
  187.     precache_model ("progs/demon.mdl");
  188.     precache_model ("progs/h_demon.mdl");
  189.  
  190.     precache_sound ("demon/ddeath.wav");
  191.     precache_sound ("demon/dhit2.wav");
  192.     precache_sound ("demon/djump.wav");
  193.     precache_sound ("demon/dpain1.wav");
  194.     precache_sound ("demon/idle1.wav");
  195.     precache_sound ("demon/sight2.wav");
  196.  
  197.     self.solid = SOLID_SLIDEBOX;
  198.     self.movetype = MOVETYPE_STEP;
  199.  
  200.     setmodel (self, "progs/demon.mdl");
  201.  
  202.     setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
  203.     self.health = 300;
  204.  
  205.     self.th_stand = demon1_stand1;
  206.     self.th_walk = demon1_walk1;
  207.     self.th_run = demon1_run1;
  208.     self.th_die = demon_die;
  209.     self.th_melee = Demon_MeleeAttack;      // one of two attacks
  210.     self.th_missile = demon1_jump1;         // jump attack
  211.     self.th_pain = demon1_pain;
  212.  
  213.     walkmonster_start();
  214. };
  215.  
  216.  
  217. /*
  218. ==============================================================================
  219.  
  220. DEMON
  221.  
  222. ==============================================================================
  223. */
  224.  
  225. /*
  226. ==============
  227. CheckDemonMelee
  228.  
  229. Returns TRUE if a melee attack would hit right now
  230. ==============
  231. */
  232. float() CheckDemonMelee =
  233. {
  234.     if (enemy_range == RANGE_MELEE)
  235.     {   // FIXME: check canreach
  236.         self.attack_state = AS_MELEE;
  237.         return TRUE;
  238.     }
  239.     return FALSE;
  240. };
  241.  
  242. /*
  243. ==============
  244. CheckDemonJump
  245.  
  246. ==============
  247. */
  248. float() CheckDemonJump =
  249. {
  250.     local   vector  dist;
  251.     local   float   d;
  252.  
  253.     if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
  254.     + 0.75 * self.enemy.size_z)
  255.         return FALSE;
  256.  
  257.     if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
  258.     + 0.25 * self.enemy.size_z)
  259.         return FALSE;
  260.  
  261.     dist = self.enemy.origin - self.origin;
  262.     dist_z = 0;
  263.  
  264.     d = vlen(dist);
  265.  
  266.     if (d < 100)
  267.         return FALSE;
  268.  
  269.     if (d > 200)
  270.     {
  271.         if (random() < 0.9)
  272.             return FALSE;
  273.     }
  274.  
  275.     return TRUE;
  276. };
  277.  
  278. float() DemonCheckAttack =
  279. {
  280.     local   vector  vec;
  281.  
  282. // if close enough for slashing, go for it
  283.     if (CheckDemonMelee ())
  284.     {
  285.         self.attack_state = AS_MELEE;
  286.         return TRUE;
  287.     }
  288.  
  289.     if (CheckDemonJump ())
  290.     {
  291.         self.attack_state = AS_MISSILE;
  292.         sound (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM);
  293.         return TRUE;
  294.     }
  295.  
  296.     return FALSE;
  297. };
  298.  
  299.  
  300. //===========================================================================
  301.  
  302. void(float side)    Demon_Melee =
  303. {
  304.     local   float   ldmg;
  305.     local vector    delta;
  306.  
  307.     ai_face ();
  308.     walkmove (self.ideal_yaw, 12);  // allow a little closing
  309.  
  310.     delta = self.enemy.origin - self.origin;
  311.  
  312.     if (vlen(delta) > 100)
  313.         return;
  314.     if (!CanDamage (self.enemy, self))
  315.         return;
  316.  
  317.     sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
  318.     ldmg = 10 + 5*random();
  319.     T_Damage (self.enemy, self, self, ldmg);
  320.  
  321.     makevectors (self.angles);
  322.     SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
  323. };
  324.  
  325.  
  326. void()  Demon_JumpTouch =
  327. {
  328.     local   float   ldmg;
  329.  
  330.     if (self.health <= 0)
  331.         return;
  332.  
  333.     if (other.takedamage)
  334.     {
  335.         if ( vlen(self.velocity) > 400 )
  336.         {
  337.             ldmg = 40 + 10*random();
  338.             T_Damage (other, self, self, ldmg);
  339.         }
  340.     }
  341.  
  342.     if (!checkbottom(self))
  343.     {
  344.         if (self.flags & FL_ONGROUND)
  345.         {   // jump randomly to not get hung up
  346. //dprint ("popjump\n");
  347.     self.touch = SUB_Null;
  348.     self.think = demon1_jump1;
  349.     self.nextthink = time + 0.1;
  350.  
  351. //          self.velocity_x = (random() - 0.5) * 600;
  352. //          self.velocity_y = (random() - 0.5) * 600;
  353. //          self.velocity_z = 200;
  354. //          self.flags = self.flags - FL_ONGROUND;
  355.         }
  356.         return; // not on ground yet
  357.     }
  358.  
  359.     self.touch = SUB_Null;
  360.     self.think = demon1_jump11;
  361.     self.nextthink = time + 0.1;
  362. };
  363.  
  364.